using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 圈地游戏碰撞检测服务接口
/// 负责处理画线轨迹碰撞、边界检测、道具拾取等核心碰撞检测逻辑
/// 采用线段相交算法，提供高精度碰撞检测，避免误判
/// </summary>
public interface ICollisionDetectionService
{
    /// <summary>
    /// 检测轨迹截断碰撞
    /// 检测玩家移动路径是否与其他玩家的轨迹相交（最核心的死亡判定）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">移动的玩家标识</param>
    /// <param name="fromPosition">移动起始位置</param>
    /// <param name="toPosition">移动目标位置</param>
    /// <param name="isDrawing">该玩家是否正在画线</param>
    /// <returns>轨迹碰撞检测结果</returns>
    Task<TrailCollisionResult> CheckTrailCollisionAsync(
        Guid gameId, 
        Guid playerId, 
        Position fromPosition, 
        Position toPosition, 
        bool isDrawing);

    /// <summary>
    /// 检测地图边界碰撞
    /// 检查玩家移动是否超出圆形地图边界
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="position">要检测的位置</param>
    /// <returns>边界碰撞结果</returns>
    Task<BoundaryCollisionResult> CheckMapBoundaryAsync(Guid gameId, Position position);

    /// <summary>
    /// 检测障碍物碰撞
    /// 检测玩家移动路径是否与地图中的固定障碍物相交
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="fromPosition">移动起始位置</param>
    /// <param name="toPosition">移动目标位置</param>
    /// <returns>障碍物碰撞结果</returns>
    Task<ObstacleCollisionResult> CheckObstacleCollisionAsync(
        Guid gameId, 
        Position fromPosition, 
        Position toPosition);

    /// <summary>
    /// 检测道具拾取碰撞
    /// 检测玩家是否接近地图上的道具（拾取距离20像素内）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="playerPosition">玩家当前位置</param>
    /// <param name="pickupRadius">拾取范围</param>
    /// <returns>道具拾取碰撞结果</returns>
    Task<PowerUpPickupCollisionResult> CheckPowerUpPickupAsync(
        Guid gameId, 
        Guid playerId, 
        Position playerPosition, 
        float pickupRadius = 20f);

    /// <summary>
    /// 检测领地进入/离开
    /// 检测玩家是否进入或离开某个玩家的领地区域
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">移动的玩家标识</param>
    /// <param name="fromPosition">移动起始位置</param>
    /// <param name="toPosition">移动目标位置</param>
    /// <returns>领地进入/离开结果</returns>
    Task<TerritoryTransitionResult> CheckTerritoryTransitionAsync(
        Guid gameId, 
        Guid playerId, 
        Position fromPosition, 
        Position toPosition);

    /// <summary>
    /// 检测轨迹预警
    /// 检测敌方玩家是否接近自己的轨迹（3像素内预警）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">轨迹所有者</param>
    /// <param name="threatPlayerPosition">威胁玩家位置</param>
    /// <param name="warningDistance">预警距离</param>
    /// <returns>轨迹预警结果</returns>
    Task<TrailWarningResult> CheckTrailWarningAsync(
        Guid gameId, 
        Guid playerId, 
        Position threatPlayerPosition, 
        float warningDistance = 3f);

    /// <summary>
    /// 检测炸弹道具影响范围
    /// 检测炸弹道具爆炸范围内的所有轨迹和玩家
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="explosionCenter">爆炸中心位置</param>
    /// <param name="explosionRadius">爆炸半径</param>
    /// <returns>爆炸影响检测结果</returns>
    Task<ExplosionCollisionResult> CheckBombExplosionAsync(
        Guid gameId, 
        Position explosionCenter, 
        float explosionRadius = 30f);

    /// <summary>
    /// 检测圈地闭合
    /// 检测玩家画线轨迹是否与自己的领地形成闭合回路
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="currentTrail">当前画线轨迹</param>
    /// <param name="endPosition">结束位置</param>
    /// <returns>圈地闭合检测结果</returns>
    Task<EnclosureDetectionResult> CheckTerritoryEnclosureAsync(
        Guid gameId, 
        Guid playerId, 
        List<Position> currentTrail, 
        Position endPosition);

    /// <summary>
    /// 检测地图缩圈影响
    /// 检测地图缩圈时哪些玩家的领地会受到影响
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="newMapRadius">新的地图半径</param>
    /// <returns>地图缩圈影响结果</returns>
    Task<MapShrinkCollisionResult> CheckMapShrinkCollisionAsync(Guid gameId, float newMapRadius);

    /// <summary>
    /// 批量碰撞检测优化
    /// 一次性检测多个玩家的移动碰撞，提高服务器性能
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerMovements">玩家移动列表</param>
    /// <returns>批量碰撞检测结果</returns>
    Task<BatchCollisionResult> CheckBatchPlayerMovementsAsync(
        Guid gameId, 
        List<PlayerMovement> playerMovements);
}

/// <summary>
/// 轨迹碰撞检测结果
/// </summary>
public class TrailCollisionResult
{
    public bool HasCollision { get; set; }
    public Guid? CollidedWithPlayerId { get; set; }
    public Position CollisionPoint { get; set; } = new();
    public bool IsDeadly { get; set; } // 是否导致死亡
    public bool CanPassThrough { get; set; } // 是否可以穿过（幽灵模式）
    public bool ShieldBlocked { get; set; } // 是否被护盾阻挡
    public string CollisionType { get; set; } = string.Empty; // Trail, SelfTrail, Territory
}

/// <summary>
/// 边界碰撞结果
/// </summary>
public class BoundaryCollisionResult
{
    public bool IsOutOfBounds { get; set; }
    public Position ValidPosition { get; set; } = new(); // 修正后的有效位置
    public float DistanceFromCenter { get; set; }
    public float MapRadius { get; set; }
    public string BoundaryType { get; set; } = "Circle";
}

/// <summary>
/// 障碍物碰撞结果
/// </summary>
public class ObstacleCollisionResult
{
    public bool HasCollision { get; set; }
    public List<MapObstacle> CollidedObstacles { get; set; } = new();
    public Position ValidPosition { get; set; } = new();
    public bool BlocksMovement { get; set; } = true;
}

/// <summary>
/// 道具拾取碰撞结果
/// </summary>
public class PowerUpPickupCollisionResult
{
    public bool CanPickup { get; set; }
    public List<PickupablePowerUp> NearbyPowerUps { get; set; } = new();
    public PickupablePowerUp? ClosestPowerUp { get; set; }
    public float ClosestDistance { get; set; }
}

/// <summary>
/// 领地转换结果
/// </summary>
public class TerritoryTransitionResult
{
    public bool TerritoryChanged { get; set; }
    public Guid? PreviousOwnerId { get; set; }
    public Guid? CurrentOwnerId { get; set; }
    public string? PreviousOwnerName { get; set; }
    public string? CurrentOwnerName { get; set; }
    public TerritoryTransitionType TransitionType { get; set; }
    public float SpeedModifier { get; set; } = 1.0f; // 在不同领地的速度修正
}

/// <summary>
/// 轨迹预警结果
/// </summary>
public class TrailWarningResult
{
    public bool ShouldWarn { get; set; }
    public List<TrailThreat> Threats { get; set; } = new();
    public TrailThreat? ImmediateThreat { get; set; }
    public float MinimumDistance { get; set; }
}

/// <summary>
/// 爆炸碰撞结果
/// </summary>
public class ExplosionCollisionResult
{
    public bool HasTargets { get; set; }
    public List<Guid> AffectedPlayerTrails { get; set; } = new();
    public List<Position> ClearedTrailPoints { get; set; } = new();
    public decimal TerritoryAreaGained { get; set; }
    public List<Position> NewTerritoryBoundary { get; set; } = new();
}

/// <summary>
/// 圈地闭合检测结果
/// </summary>
public class EnclosureDetectionResult
{
    public bool IsEnclosed { get; set; }
    public List<Position> EnclosedArea { get; set; } = new();
    public decimal AreaSize { get; set; }
    public List<Guid> EnclosedPlayerTerritories { get; set; } = new(); // 被包围的敌方领地
    public bool IsValidEnclosure { get; set; }
    public string? InvalidReason { get; set; }
}

/// <summary>
/// 地图缩圈碰撞结果
/// </summary>
public class MapShrinkCollisionResult
{
    public bool HasAffectedTerritories { get; set; }
    public List<PlayerTerritoryLoss> TerritoryLosses { get; set; } = new();
    public float NewMapRadius { get; set; }
    public Position MapCenter { get; set; } = new();
    public int TotalAffectedPlayers { get; set; }
}

/// <summary>
/// 批量碰撞检测结果
/// </summary>
public class BatchCollisionResult
{
    public List<PlayerCollisionResult> Results { get; set; } = new();
    public int TotalCollisions { get; set; }
    public int ProcessedMovements { get; set; }
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 玩家移动信息
/// </summary>
public class PlayerMovement
{
    public Guid PlayerId { get; set; }
    public Position FromPosition { get; set; } = new();
    public Position ToPosition { get; set; } = new();
    public bool IsDrawing { get; set; }
    public long Timestamp { get; set; }
    public float Speed { get; set; }
}

/// <summary>
/// 玩家碰撞结果
/// </summary>
public class PlayerCollisionResult
{
    public Guid PlayerId { get; set; }
    public bool HasCollision { get; set; }
    public Position ValidPosition { get; set; } = new();
    public List<CollisionDetail> Collisions { get; set; } = new();
    public bool ShouldDie { get; set; }
    public string? DeathReason { get; set; }
}

/// <summary>
/// 地图障碍物
/// </summary>
public class MapObstacle
{
    public Guid Id { get; set; }
    public List<Position> Boundary { get; set; } = new();
    public string ObstacleType { get; set; } = "Static"; // Static, Destructible
    public bool IsDestructible { get; set; }
    public Position Center { get; set; } = new();
    public float Radius { get; set; }
}

/// <summary>
/// 可拾取道具
/// </summary>
public class PickupablePowerUp
{
    public Guid Id { get; set; }
    public TerritoryGamePowerUpType Type { get; set; }
    public Position Position { get; set; } = new();
    public float DistanceFromPlayer { get; set; }
    public bool IsPickupable { get; set; } = true;
    public DateTime SpawnTime { get; set; }
}

/// <summary>
/// 轨迹威胁
/// </summary>
public class TrailThreat
{
    public Guid ThreatPlayerId { get; set; }
    public Position ThreatPosition { get; set; } = new();
    public Position NearestTrailPoint { get; set; } = new();
    public float Distance { get; set; }
    public ThreatLevel Level { get; set; }
    public float TimeToContact { get; set; } // 预计接触时间（秒）
}

/// <summary>
/// 玩家领地损失
/// </summary>
public class PlayerTerritoryLoss
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public decimal AreaLost { get; set; }
    public decimal RemainingArea { get; set; }
    public List<Position> LostTerritoryBoundary { get; set; } = new();
}

/// <summary>
/// 碰撞详情
/// </summary>
public class CollisionDetail
{
    public CollisionCategory Category { get; set; }
    public Position CollisionPoint { get; set; } = new();
    public Guid? OtherPlayerId { get; set; }
    public string Description { get; set; } = string.Empty;
    public Dictionary<string, object> Properties { get; set; } = new();
}

/// <summary>
/// 领地转换类型
/// </summary>
public enum TerritoryTransitionType
{
    NeutralToOwned,    // 从中立区域进入玩家领地
    OwnedToNeutral,    // 从玩家领地进入中立区域
    OwnedToOtherOwned, // 从一个玩家领地进入另一个玩家领地
    NoChange           // 没有变化
}

/// <summary>
/// 威胁等级
/// </summary>
public enum ThreatLevel
{
    None,      // 无威胁
    Low,       // 低威胁
    Medium,    // 中等威胁  
    High,      // 高威胁
    Critical   // 紧急威胁
}

/// <summary>
/// 碰撞分类
/// </summary>
public enum CollisionCategory
{
    TrailCollision,    // 轨迹碰撞
    BoundaryHit,       // 边界碰撞
    ObstacleHit,       // 障碍物碰撞
    TerritoryTransition, // 领地转换
    PowerUpPickup      // 道具拾取
}
